package biblioteca.model;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import biblioteca.controller.LocacaoNaoEncontradaException;
import biblioteca.controller.UsuarioNaoEncontradoException;

import com.mysql.jdbc.PreparedStatement;

/**
 * Classe responsavel por gerenciar a classe Usuario com metods de insercao
 * e delecao de dados. Atrubutos: connection e stmt.
 * @author willen leiros e fabio queiroz
 *
 */

public class GerenciarUsuario {
	
	private Connection connection;
	private PreparedStatement stmt;
	
	/**
	 * Construtor da classe responsavel por iniciar uma conexao com o Banco de Dados.
	 */
	
	public GerenciarUsuario(){
		this.connection = new ConnectionFactory().getConnection();
	}
	/**
	 * Esse metodo inseri o objeto usuario no Banco de Dados.
	 * @param usuario Parametro do tipo Usuario que representa o objeto usuario.
	 * @return boolean Se adicionado com sucesso retorna true, se nao falso.
	 */
	
	public boolean addUsuario(Usuario usuario){
		String sql = "insert into Usuario " + "(nome,endereco,cpf,userName,senha,sit)"
				+ " values (?,?,?,?,?,?)";
		
		try {
			PreparedStatement stmt = (PreparedStatement) connection
					.prepareStatement(sql);
			
				
				stmt.setString(1, usuario.getNome());
				stmt.setString(2, usuario.getEndereco());
				stmt.setString(3, usuario.getCpf());
				stmt.setString(4, usuario.getUserName());
				stmt.setString(5, usuario.getSenha());
				stmt.setInt(6, usuario.getSit());
			

			stmt.execute();
			stmt.close();
			return true;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}
	/**
	 * Esse metodo deleta um usuario do Banco de Dados.
	 * @param codUsuario Parametro do tipo inteiro que representa o codigo do usuario.
	 */
	
	public void deleteUsuario(int codUsuario){

		try {
			PreparedStatement stmt = (PreparedStatement) connection
					.prepareStatement("delete from Usuario where codUsuario=?");
			stmt.setLong(1, codUsuario);
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);

		}
	}
	/**
	 * Esse metodo retorna a situacao de um usuario atraves de uma String contendo
	 * uma lista com todos os itens que o mesmo ja locou. O item e descrito com a 
	 * data do aluguel, a data de entrega, informa se o mesmo ja foi entregue e o 
	 * valor da multa, caso tenha gerado.
	 * 
	 * @param codUsuario Parametro do tipo inteiro que representa o codigo do usuario.
	 * @return situacao Representa uma lista com todos os itens locados que foram entregues e que ainda serao entregues.
	 * @throws LocacaoNaoEncontradaException Lança uma mensagem de erro quando o usuario nao é localizado no Banco de Dados.
	 */
	
	public ArrayList<String> sitUsuario(int codUsuario) 
									throws LocacaoNaoEncontradaException{
		ArrayList<String> situacao = new ArrayList<String>();
		SimpleDateFormat dataAluguel =  new SimpleDateFormat("dd-MM-yyyy");
		SimpleDateFormat dataDevolucao =  new SimpleDateFormat("dd-MM-yyyy");
		SimpleDateFormat dataEntrega =  new SimpleDateFormat("dd-MM-yyyy");
		try {
			
			PreparedStatement stmt = (PreparedStatement) connection
					.prepareStatement(" select Locacao.dataAluguel, Locacao.dataDevolucao, Locacao.dataEntrega, Locacao.custo, Usuario.nome, Usuario.codUsuario, Item.codItem, Item.titulo "
							+ "			from "
							+ "				Leiros01.Locacao, Leiros01.Usuario, Leiros01.Item "
							+ "			where "
							+ "				Locacao.Usuario_codUsuario="+"\'"+codUsuario+"\'"
							+ "			and "
							+ "				Locacao.Usuario_codUsuario = Usuario.codUsuario"
							+ "			and "
							+ "				Locacao.Item_codItem = Item.codItem"
							+ "			and "
							+ "				Locacao.Usuario_codUsuario ="+"\'"+codUsuario+"\'");
			
			ResultSet rs = stmt.executeQuery();

			while (rs.next()) {
				situacao.add("Código Usuário: "+rs.getInt("codUsuario"));
				situacao.add( "Nome Usuário: "+rs.getString("nome"));
				situacao.add("Codigo item: "+rs.getInt("codItem"));
				situacao.add("Titulo Item: "+ rs.getString("titulo"));
				situacao.add("Data do Aluguel: "+dataAluguel.format((rs.getDate("dataAluguel"))));
				situacao.add("Data da Devolução: "+dataDevolucao.format((rs.getDate("dataDevolucao"))));
				
				if (rs.getString("dataEntrega") == null){
					situacao.add("Data de Entrega: não foi entregue");
				}
				else{
					situacao.add("Data de Entrega: "+dataEntrega.format((rs.getDate("dataEntrega"))));
				}
				
				situacao.add("Custo: "+String.valueOf(rs.getDouble("custo")));
			
			}
			rs.close();
			stmt.close();
			
			if (situacao.size() == 0){
				throw new LocacaoNaoEncontradaException("Usuário não alugou itens...");
			}
			else{
				return situacao;
			}
		
		} catch (SQLException e) {
			throw new RuntimeException(e);

		}
	}
	
	/**
	 * Esse metodo retorna uma lista de todos os usuarios cadastrados no Banco de Dados
	 * @return usuarios
	 */
	
	public ArrayList<Usuario> getUsuarios(){
		ArrayList<Usuario> usuarios = new ArrayList<Usuario>();
		try {
			stmt = (PreparedStatement) this.connection
					.prepareStatement("select codUsuario,nome,cpf from Usuario");
			
			ResultSet rs = stmt.executeQuery();

			while (rs.next()) {
				Usuario usuario = new Usuario();
				usuario.setCodUsuario(rs.getInt("codUsuario"));
				usuario.setNome(rs.getString("nome"));
				usuario.setCpf(rs.getString("cpf"));
				usuarios.add(usuario);
			}
			rs.close();
			stmt.close();
			return usuarios;

		} 
		catch (SQLException e) {
			throw new RuntimeException(e);
		}

	}
	
	/**
	 * Esse metodo retorna um usuario cadastrado no Banco de dados.
	 * @param codUsuario Parametro do tipo inteiro que representa o codigo do usuario.
	 * @return usuario 
	 * @throws UsuarioNaoEncontradoException Lanca uma mensagem de erro quando o usuario não e localizado no Banco de dados
	 */
	
	public Usuario getUsuario(int codUsuario) throws UsuarioNaoEncontradoException{
		try {
			Usuario usuario = null;
			stmt = (PreparedStatement) this.connection
					.prepareStatement("select codUsuario,nome,cpf from Leiros01.Usuario where codUsuario = "+codUsuario);
			
			ResultSet rs = stmt.executeQuery();

			while (rs.next()) {
				usuario = new Usuario();
				usuario.setCodUsuario(rs.getInt("codUsuario"));
				usuario.setNome(rs.getString("nome"));
				usuario.setCpf(rs.getString("cpf"));
			}
			rs.close();
			stmt.close();
			
			if (usuario == null){
				throw new UsuarioNaoEncontradoException("Usuário não encontrado...");
			}
			else{
				return usuario;
			}
			
		} 
		catch (SQLException e) {
			throw new RuntimeException(e);
		}

	}
	
	/**
	 * Esse metodo retorna um usuario que conseguiu logar no sistema com os dados corretos.
	 * @param userName Parametro do tipo String que representa o userName do usuario.
	 * @param senha Parametro do tipo String que representa a senha do usuario.
	 * @return usuario Retorna o usuario que foi logado com sucesso.
	 */
	public Usuario getLogin(String userName, String senha){
		Usuario usuario = null;
		try {
			stmt = (PreparedStatement) this.connection
					.prepareStatement("select codUsuario,nome,cpf,sit from Usuario where userName = "+"\'"+userName+"\' and senha = "+"\'"+senha+"\'");

			ResultSet rs = stmt.executeQuery();

			while (rs.next()) {
				usuario = new Usuario();
				usuario.setCodUsuario(rs.getInt("codUsuario"));
				usuario.setNome(rs.getString("nome"));
				usuario.setCpf(rs.getString("cpf"));
				usuario.setSit(rs.getInt("sit"));
				
			}
			
			rs.close();
			stmt.close();
			
			if (usuario == null){
				return null;
			}
			else{
				return usuario;
			}
			
		} 
		catch (SQLException e) {
			throw new RuntimeException(e);
		}

	}
}
